home *** CD-ROM | disk | FTP | other *** search
- ;;; -*- Scheme -*-
-
- (declare (usual-integrations))
-
- (let-syntax ((define-integrable
- (macro (params . body)
- `(begin
- (declare (integrate-operator ,(car params)))
- (define ,(car params)
- (named-lambda ,params
- (declare (integrate ,@(cdr params)))
- ,@body))))))
-
- (define (sort obj pred)
- (cond ((pair? obj)
- (vector->list (sort! (list->vector obj) pred)))
- ((vector? obj)
- (sort! (vector-copy obj) pred))
- ((null? obj)
- '())
- (else
- (error "sort: argument should be a list or a vector"))))
-
- (define (sort! vec pred)
- (define-integrable (exchange! i j)
- (let ((old (vector-ref vec i)))
- (vector-set! vec i (vector-ref vec j))
- (vector-set! vec j old)))
-
- (define (heapify-up n)
- (let ((next (quotient (-1+ n) 2)))
- (if (and (not (zero? n))
- (not (pred (vector-ref vec n)
- (vector-ref vec next))))
- (begin
- (exchange! n next)
- (heapify-up next)))))
-
- (define (heapify-down n max)
- (define-integrable (check m)
- (if (pred (vector-ref vec n)
- (vector-ref vec m))
- (begin
- (exchange! n m)
- (heapify-down m max))))
-
- (let* ((p (+ n n 1))
- (q (1+ p)))
- (if (and (<= q max)
- (not (pred (vector-ref vec q)
- (vector-ref vec p))))
- (check q)
- (if (<= p max)
- (check p)))))
-
- (if (not (vector? vec))
- (error "sort!: argument must be a vector" vec))
-
- (let ((max (-1+ (vector-length vec))))
-
- (define (heapify-loop n)
- (if (<= n max)
- (begin
- (heapify-up n)
- (heapify-loop (1+ n)))))
-
- (define (sort-loop dest)
- (if (> dest 0)
- (begin
- (exchange! dest 0)
- (heapify-down 0 (-1+ dest))
- (sort-loop (-1+ dest)))))
-
- (heapify-loop 0)
- (sort-loop max)
- vec))
- ) ;; End of let-syntax